﻿namespace Sai.Core
{
	using System.Collections.Generic;
	using Sai.Core.Introspection;
	using Sai.Core.Rules;

	public class AssemblyIntrospectionWalker : IWalkIntrospectedAssemblies
	{
		private List<IAssemblyRule> rules = new List<IAssemblyRule>();

        public void Walk(IntrospectedAssembly first, IntrospectedAssembly second, IWalkTypeDifferences walker, IAssemblyDifference assemblyDifference, IProductReleaseProject project)
		{
			foreach (var rule in this.rules)
			{
				rule.Validate(first, second, assemblyDifference);
			}

			var commonTypes = second.TypesInCommonWith(first);

            var factory = new TypeDifferenceFactory();

			foreach (var commonType in commonTypes)
			{
				var firstType = first.Lookup(commonType);
				var secondType = second.Lookup(commonType);

                var diffs = factory.Create(firstType, project);

				walker.Walk(firstType, secondType, diffs);

				if (diffs.HasChanged)
				{
					assemblyDifference.Changed(diffs);
				}
			}
		}

		public void Add(IAssemblyRule rule)
		{
			this.rules.Add(rule);
		}

		public void AddRange(IEnumerable<IAssemblyRule> rules)
		{
			this.rules.AddRange(rules);
		}
	}
}
